var fileInpElem = document.querySelector('#J_FileInput');
var imgCutviewContainerElem = document.querySelector('#J_ImgCutviewContainer');
var imgPreviewElem = imgCutviewContainerElem.querySelector('.J_ImgPreview'); 
var cutViewElem = imgCutviewContainerElem.querySelector('.J_CutView');
var resizeBtnElem = cutViewElem.querySelector('.J_ResizeBtn');
var cutButtonElem  = imgCutviewContainerElem.querySelector('.J_CutButton');
(async () => {
    const cutInfo = {};
    // 完成本地预览
    const imgInfo = await localPreview();
    cutButtonElem.style.display = 'block';
    // 设置选框交互（移动，大小拖拽）
    createCutViewController(imgInfo, cutInfo);
    // 截取图片的操作
    // 裁切后图片进行本地预览和上传到服务器
    generateCutedImage(cutInfo, handlerCutedImage);
})();
// step: 1 读取图片形成本地预览
function localPreview(){
    return new Promise((resolve) => {
        fileInpElem.addEventListener('change', (event) => {
            // 获取文件对象
            const imgFile = event.target.files[0];
            // imgFile.type 检测下文件IMIE类型是 图片
            var reader = new FileReader();
            reader.onload = function () {
                // 文件的 URLDATA识别的base64 字符串(带 MIME-TYPE 的)
                var fileUrl = reader.result;
                // 本地预览效果
                var img = new Image();
                img.onload = () => {
                    var viewWidth = img.width;
                    var viewHeight = img.height;
                    if(img.width > img.height){
                        if(img.width > 400){
                            viewWidth = 400;
                            viewHeight = Math.floor(400/img.width*img.height);
                        }
                    }else{
                        if(img.height > 400){
                            viewHeight = 400;
                            viewHeight = Math.floor(400/img.height*img.width);   
                        }
                    }
                    imgCutviewContainerElem.style.cssText = `
                        width:${viewWidth}px;
                        height:${viewHeight}px;
                    `;
                    imgPreviewElem.style.cssText = `
                        width: 100%;
                        height: 100%;
                        filter: contrast(0.2);
                        background: url(${fileUrl}) no-repeat;
                        background-size: 100% 100%;`;
                    resolve({
                        url: fileUrl,
                        imgElem: img,
                        width: viewWidth,
                        height: viewHeight,
                    });
                }
                img.src = fileUrl;
            }
            reader.readAsDataURL(imgFile);
        }, false);
    });
}
// step: 2 生成裁切交互
function createCutViewController(imgInfo, cutInfo){
    // 初始化操作窗口
    cutViewElem.style.cssText = `
        background: url(${imgInfo.url}) no-repeat;
        background-size: ${imgInfo.width}px ${imgInfo.height}px;
        background-position: 0px 0px;
        width: 100px;
        height: 100px;
        left: 0px;
        top: 0px;
        display: block;
    `;
    // 公用属性
    let mouseDown = false;
    let operateType = ''; // move 移动 resize 改变大小
    let startX = 0;
    let startY = 0;
    // resize时用到的
    let viewWidth = cutViewElem.offsetWidth;
    let viewHeight = cutViewElem.offsetHeight;
    const CutMinWidth = 50;
    const CutMinHeight = 50;
    let CutMaxWidth = 0;
    let CutMaxHeight = 0;
    // move时用到的
    let viewPosLeft = cutViewElem.offsetLeft;
    let viewPosTop = cutViewElem.offsetTop;
    const CutMinLeft = 0;
    const CutMinTop = 0;
    let CutMaxLeft = 0;
    let CutMaxTop = 0;
    // 初始化裁切数据
    cutInfo.url = imgInfo.url;
    cutInfo.originImgElem = imgInfo.imgElem;
    cutInfo.originWidth = imgInfo.width;
    cutInfo.originHeight = imgInfo.height;
    cutInfo.cutWidth = viewWidth;
    cutInfo.cutHeight = viewHeight;
    cutInfo.cutLeft = viewPosLeft;
    cutInfo.cutTop = viewPosTop;
    // 设置操作
    cutViewElem.addEventListener('mousedown', (event) => {
        mouseDown = true;
        const target = event.target;
        startX = event.pageX;
        startY = event.pageY;
        if(target === resizeBtnElem){
            operateType = 'resize';
            viewWidth = cutViewElem.offsetWidth;
            viewHeight = cutViewElem.offsetHeight;
            CutMaxWidth = imgInfo.width - cutViewElem.offsetLeft;
            CutMaxHeight = imgInfo.height - cutViewElem.offsetTop;
        }else{
            operateType = 'move';
            viewWidth = cutViewElem.offsetWidth;
            viewHeight = cutViewElem.offsetHeight;
            viewPosLeft = cutViewElem.offsetLeft;
            viewPosTop = cutViewElem.offsetTop;
            CutMaxLeft = imgInfo.width - viewWidth;
            CutMaxTop = imgInfo.height - viewHeight;
        }
    });
    document.addEventListener('mousemove', (event) => {
        event.preventDefault();
        event.stopPropagation();
        if(!mouseDown) return;
        let curX = event.pageX;
        let curY = event.pageY;
        let changeX = curX - startX;
        let changeY = curY - startY;
        if(operateType === 'resize'){ // 控制选取面积大小
            let changedWidth = viewWidth + changeX;
            let changedHeight = viewHeight + changeY;
            changedWidth < CutMinWidth && (changedWidth = CutMinWidth);
            changedWidth > CutMaxWidth && (changedWidth = CutMaxWidth);
            changedHeight < CutMinHeight && (changedHeight = CutMinHeight);
            changedHeight > CutMaxHeight && (changedHeight = CutMaxHeight);
            cutViewElem.style.width = `${changedWidth}px`;
            cutViewElem.style.height = `${changedHeight}px`;
            // 实时保存操作数据
            cutInfo.cutWidth = changedWidth;
            cutInfo.cutHeight = changedHeight;
        }else{
            let changedLeft = viewPosLeft + changeX;
            let changedTop = viewPosTop + changeY;
            changedLeft < CutMinLeft && (changedLeft = CutMinLeft);
            changedLeft > CutMaxLeft && (changedLeft = CutMaxLeft);
            changedTop < CutMinTop && (changedTop = CutMinTop);
            changedTop > CutMaxTop && (changedTop = CutMaxTop);
            cutViewElem.style.left = `${changedLeft}px`;
            cutViewElem.style.top = `${changedTop}px`;
            cutViewElem.style.backgroundPosition = `${-changedLeft}px -${changedTop}px`;
            // 实时保存操作数据
            cutInfo.cutLeft = changedLeft;
            cutInfo.cutTop = changedTop;
        }
    });
    // 这里要监听全局的操作，因为可能会超出区域松手
    document.addEventListener('mouseup', () => {
        mouseDown = false;
    });
}
// step: 3 使用canvas进行图片裁切
function generateCutedImage(cutInfo, cutCallback){
    cutButtonElem.addEventListener('click', () => {
        // 读取图片在缩放后的宽高，在canvas中进行渲染
        let canvas = document.createElement('canvas');
        canvas.setAttribute('width', `${cutInfo.originWidth}`);
        canvas.setAttribute('height', `${cutInfo.originHeight}`);
        let ctx = canvas.getContext('2d');
        // 绘制整个图片，在根据参数读取对应像素数据
        ctx.drawImage(
            cutInfo.originImgElem, 
            0, 0, 
            cutInfo.originWidth, cutInfo.originHeight,
        );
        let curImageData = ctx.getImageData(cutInfo.cutLeft, cutInfo.cutTop, cutInfo.cutWidth, cutInfo.cutHeight);
        canvas = document.createElement('canvas');
        canvas.setAttribute('width', `${cutInfo.cutWidth}`);
        canvas.setAttribute('height', `${cutInfo.cutHeight}`);
        ctx = canvas.getContext('2d');
        ctx.putImageData(curImageData, 0, 0, 0, 0, cutInfo.cutWidth, cutInfo.cutHeight);
        let imgURL = canvas.toDataURL("image/png"); // base64，可以直接发送给服务器作为请求
        cutCallback(imgURL);
    }, false)
}
// step: 4 裁切后的图片进行本地预览和文件上传操作
function handlerCutedImage (imageUrl){
    //case1: cut后的图片本地预览
    let imgElem = document.createElement('img');
    imgElem.src = imageUrl;
    document.body.appendChild(imgElem);
    //case2: 上传到服务器端 
    const formData = new FormData();
    formData.append('croppedImage', imageUrl);
    window.fetch('http://localhost:8080/api/upload', {
        method: "POST",
        body: formData
    }).then((response) => {
        return response.json();
    }).then((result) => {
        console.log(result);
        console.log(result.data.path);
    });
}